package com.oldking.utils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class FFmpegUtil {

    public static void downloadm3u8() throws InterruptedException, IOException {
//        https://lajiaoapi.com/watch?url=https://lajiao-bo.com/20190616/RfPX8oPL/index.m3u8
        File file = new File("");
        List<String> commend = new ArrayList<String>();
        //commend.add(file.getCanonicalPath()+"/ffmpeg.exe");
        commend.add(file.getCanonicalPath() + "/ffmpeg.exe");
        commend.add("-i");
        commend.add("https://lajiaoapi.com/watch?url=https://lajiao-bo.com/20190616/RfPX8oPL/index.m3u8");
        commend.add("-copy");

        commend.add("F:\\video\\test.mp4");
        ProcessBuilder builder = new ProcessBuilder();
        builder.command(commend);
        builder.redirectErrorStream(true);
        Process process = builder.start();
        process.waitFor();// 等待进程执行结束
    }

    public static String composeVideo(boolean flag, String path, String outFilePath, String startTime, String endTime) {
        if (!checkfile(path)) {
            System.out.println(path + " is not file");
            return "";
        }
        if (process(flag, path, outFilePath, startTime, endTime)) {
            return outFilePath;
        }
        return "";
    }

    private static boolean process(boolean flag, String path, String outFilePath, String startTime, String endTime) {
        int type = checkContentType(path);
        boolean status = false;
        if (type == 0) {
            status = processmp4(flag, path, outFilePath, startTime, endTime);// 直接将文件转为flv文件
        } else if (type == 1) {
            String avifilepath = processAVI(type, path);
            if (avifilepath == null)
                return false;// avi文件没有得到
            status = processmp4(flag, path, outFilePath, startTime, endTime);// 将avi转为flv
        }
        return status;
    }

    private static int checkContentType(String path) {
        String type = path.substring(path.lastIndexOf(".") + 1,
                path.length()).toLowerCase();
        // ffmpeg能解析的格式：（asx，asf，mpg，wmv，3gp，mp4，mov，avi，flv等）
        if (type.equals("avi")) {
            return 0;
        } else if (type.equals("mpg")) {
            return 0;
        } else if (type.equals("wmv")) {
            return 0;
        } else if (type.equals("3gp")) {
            return 0;
        } else if (type.equals("mov")) {
            return 0;
        } else if (type.equals("mp4")) {
            return 0;
        } else if (type.equals("asf")) {
            return 0;
        } else if (type.equals("asx")) {
            return 0;
        } else if (type.equals("flv")) {
            return 0;
        } else if (type.equals("mkv")) {
            return 0;
        }
        //对ffmpeg无法解析的文件格式(wmv9，rm，rmvb等),
        //可以先用别的工具（mencoder）转换为avi(ffmpeg能解析的)格式.
        else if (type.equals("wmv9")) {
            return 1;
        } else if (type.equals("rm")) {
            return 1;
        } else if (type.equals("rmvb")) {
            return 1;
        }
        return 9;
    }

    private static boolean checkfile(String path) {
        File file = new File(path);
        if (!file.isFile()) {
            return false;
        }
        return true;
    }

    //对ffmpeg无法解析的文件格式(wmv9，rm，rmvb等), 可以先用别的工具（mencoder）转换为avi(ffmpeg能解析的)格式.
    private static String processAVI(int type, String path) {
        try {
            File file = new File("");
            List<String> commend = new java.util.ArrayList<String>();
            commend.add(file.getCanonicalPath() + "/src/main/resources/mencoder/mencoder.exe");
            commend.add(path);
            commend.add("-oac");
            commend.add("lavc");
            commend.add("-lavcopts");
            commend.add("acodec=mp3:abitrate=64");
            commend.add("-ovc");
            commend.add("xvid");
            commend.add("-xvidencopts");
            commend.add("bitrate=600");
            commend.add("-of");
            commend.add("avi");
            commend.add("-o");
            String tempFiledir = path.substring(path.lastIndexOf(".") + 1, path.length());
            File tempDir = new File(tempFiledir);
            if (!tempDir.exists()) {
                tempDir.mkdirs();
            }
            String tmep = tempFiledir + "/" + UUIDUtil.getUUID() + ".avi";
            commend.add(tmep);

            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commend);
            builder.start();
            return tmep;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // fmpeg -i 音乐.mp3 -i 视频.mp4 -t 6 -filter_complex amix=inputs=2 合成后新的视频.mp4
    public static String setVideomp3Andsrt(String videoPath, String mp3Path, String srtPath, String newOutPath) {
        checkNewFileExit(newOutPath);

        if (!checkfile(videoPath)) {
            System.out.println(videoPath + " is not file");
            return "";
        }
        Process process = null;
        try {
            List<String> commend = new java.util.ArrayList<String>();
            File file = new File("");
           // commend.add(file.getCanonicalPath() + "/ffmpeg.exe");
            commend.add("D:/work/software/ffmepg/ffmpeg/bin/ffmpeg.exe");
            commend.add("-i");
            commend.add(mp3Path);
            commend.add("-i");
            commend.add(videoPath);

            commend.add("-f");
            commend.add("srt");
            commend.add("-i");
            commend.add(srtPath);
            commend.add("-c:v");
            commend.add("copy");
            //  -ar 16000 -vcodec copy
            commend.add("-ar");
            commend.add("16000");
            commend.add("-vcodec");
            commend.add("copy");
            commend.add("-c:s");
            commend.add("mov_text");
            commend.add(newOutPath);
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commend);
            process = builder.start();
            process.waitFor(25, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (!(process == null)) {
                process.destroy();
            }
            process = null;
            return newOutPath;
        }
    }

    private static void checkNewFileExit(String newOutPath) {
        File file = new File(newOutPath);
        if (file.exists()) {
            file.delete();
        }
    }

    public static String setVideoSubtitles(String videoPath, String outPutPath, String srtPath) {
        if (!checkfile(videoPath)) {
            System.out.println(videoPath + " is not file");
            return "";
        }
        try {
            //  ffmpeg -i infile.mp4 -f srt -i infile.srt -c:v copy -c:a copy -c:s mov_text outfile.mp4
            // ffmpeg -i input.mkv -i subtitles.srt -c copy output.mkv
            List<String> commend = new java.util.ArrayList<String>();
            File file = new File("");
            //commend.add(file.getCanonicalPath() + "/ffmpeg.exe");
            commend.add("D:/work/software/ffmepg/ffmpeg/bin/ffmpeg.exe");
            commend.add("-i");
            commend.add(videoPath);
            commend.add("-f");
            commend.add("srt");
            commend.add("-i");
            commend.add(srtPath);
            commend.add("-c:v");
            commend.add("copy");
            commend.add("-c:a");
            commend.add("copy");
            commend.add("-c:s");
            commend.add("mov_text");
            commend.add(outPutPath);
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commend);
            builder.start();
            return outPutPath;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    private static boolean processmp4(boolean flag, String path, String outFilePath, String startTime, String endTime) {
        if (!checkfile(path)) {
            System.out.println(path + " is not file");
            return false;
        }
        int startInt = CommonTimeUtil.Stringtime2Second(startTime);
        int endInt = CommonTimeUtil.Stringtime2Second(endTime);
        String lastTime = CommonTimeUtil.secondToTime((long) (endInt - startInt));
        Process process = null;
        try {
            List<String> commend = new java.util.ArrayList<String>();
            File file = new File("");
            // commend.add(file.getCanonicalPath() + "/ffmpeg.exe");
             commend.add("D:/work/software/ffmepg/ffmpeg/bin/ffmpeg.exe");
            commend.add("-ss");
            commend.add(startTime);
            commend.add("-t");
            commend.add(lastTime);
            commend.add("-i");
            commend.add(path);
            if (flag) {
                // -c copy -c:s mov_text
                commend.add("-c");
                commend.add("copy");
                commend.add("-c:sc");
                commend.add("mov_text");
                commend.add("-vcodec");
                commend.add("copy");
                commend.add("-an");
                commend.add("-map");
                commend.add("0");
            } else {
                commend.add("-c");
                commend.add("copy");
            }


            commend.add(outFilePath);

            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commend);
            process = builder.start();
            int exitCode = process.waitFor();
            // 取得命令结果的输出流
            InputStream is = process.getInputStream();
            // 用一个读输出流类去读
            InputStreamReader isr = new InputStreamReader(is);
            // 用缓冲器读行
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            is.close();
            isr.close();
            br.close();
            return true;
        } catch (Exception e) {

        }
        return false;

    }

    public static void commandStart(List<String> command) {
        //  command.forEach(v -> System.out.print(v + " "));
        ProcessBuilder builder = new ProcessBuilder();
        //正常信息和错误信息合并输出
        builder.redirectErrorStream(true);
        builder.command(command);
        //开始执行命令
        Process process = null;
        try {
            process = builder.start();
            //如果你想获取到执行完后的信息，那么下面的代码也是需要的
            String line = "";
            BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void mergeVideos(String fileListPath, String outPath) {

        try {
            //所有要合并的视频转换为ts格式存到videoList里
            List<String> command1 = new ArrayList<>();
            File file = new File("");
           // command1.add(file.getCanonicalPath() + "/ffmpeg.exe");
            command1.add("D:/work/software/ffmepg/ffmpeg/bin/ffmpeg.exe");
            //ffmpeg -y -safe 0 -f concat -i 1.txt -c copy 1.mp4
            command1.add("-y");
            command1.add("-safe");
            command1.add("0");
            command1.add("-f");
            command1.add("concat");
            command1.add("-i");
            command1.add(fileListPath);
            command1.add("-c");
            command1.add("copy");
            command1.add(outPath);
            commandStart(command1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean addMp3(String inputPath, String mp3Path, String outPath) {
        if (!checkfile(inputPath)) {
            System.out.println(inputPath + " is not file");
            return false;
        }
        Process process = null;
        try {
            //  ffmpeg -i a.mp4 -i a.mp3 -vf "subtitles=a.srt:force_style='Fontsize=24'" out.mp4

            List<String> commend = new java.util.ArrayList<String>();
            File file = new File("");
            String ffmpegPath = file.getCanonicalPath() + "/ffmpeg.exe";
            String command = ffmpegPath + " -i " + inputPath + " -i " + mp3Path +
                    " -ar 16000 -vcodec copy " +
                    outPath;
            process = Runtime.getRuntime().exec(command);
            process.waitFor();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean downLoadVideoMp3(String inputPath, String outPath) {

        Process process = null;
        try {
            //   ffmpeg -i input.mkv -filter_complex [0:v][0:s]overlay[v] -map [v] -map 0:a output.mp4
            List<String> commend = new java.util.ArrayList<String>();
            File file = new File("");
            String ffmpegPath = file.getCanonicalPath() + "/src/main/resources/ffmpeg.exe";
           // String ffmpegPath = "D:/work/software/ffmepg/ffmpeg/bin/ffmpeg.exe";
            String command = ffmpegPath + " -i https://2.ddyunbo.com/20191015/jQam3u54/800kb/hls/index.m3u8 " +
                    " -c copy " +
//                    String command =ffmpegPath + " -i " + inputPath +
//                    " -filter_complex [0:v][0:s]overlay[v] -map [v] -map 0:a " +
                    outPath;
            process = Runtime.getRuntime().exec(command);
            process.waitFor();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static void main(String[] args) {
//        List list = new ArrayList<>();
//        list.add("F:\\video\\666\\666.avi1.mp4");
//        list.add("F:\\video\\666\\666.avi2.mp4");
//        mergeVideos("F:\\video\\666\\666.avi2.mp4","F:\\video\\666vvavi.mp4");

        boolean flag = false;
        String path = "G:\\video\\666.avi";
        String outFilePath = "G:\\video\\666new.mp4";
        String outNewFilePath = "G:\\video\\111.mp4";
        String pathString = "G:\\video\\666\\pathString.txt";
        String resultFilePath = "G:\\video\\66633.mp4";

        String mp3Path = "G:\\video\\test2.mp3";
        String subtitlePath = "G:\\video\\test2.srt";
        String assPath = "G:\\video\\test.ass";
        String startTime = "0:03:30";
        String endTime = "0:04:50";
        // 生成视频测试
        // mergeVideos("F:\\video\\666\\fileList.txt",resultFilePath);
       // processmp4(flag, path, outFilePath, startTime, endTime);
        // setVideomp3Andsrt(outFilePath,  mp3Path, subtitlePath, resultFilePath);
          downLoadVideoMp3(outFilePath,resultFilePath);
        // addMp3(mp3Path,resultFilePath,outNewFilePath);
    }


//    public static void main(String[] args) {
//        //processmp4 是表示不要原音 flag, 视频路径 path, 输出视频路径 outFilePath, mp3路径 mp3Path, 字幕路径 subtitlePath, 开始时间 startTime, 结束时间 endTime
//        boolean flag = true;
//        String path = "F:\\video\\666.avi";
//        String outFilePath = "F:\\video\\222.mp4";
//        String outNewFilePath = "F:\\video\\2222new.mp4";
//        String pathString = "F:\\video\\666\\pathString.txt";
//        String resultFilePath = "F:\\video\\333new.mp4";
//        String mp3Path = "F:\\video\\test.mp3";
//        String subtitlePath = "F:\\video\\test1.srt";
//        String assPath = "F:\\video\\test.ass";
//        String startTime = "0:1:30";
//        String endTime = "0:0:50";
//        // 生成视频测试
//       //  String b = concatVideo(flag, path, outFilePath, startTime, endTime);
//
//        // 将视频和mp3合并到一起 取段mp3播放完 视频就完了
//     //   String mp3ResultPath = setVideomp3Andsrt(mp3Path, outFilePath, subtitlePath, outNewFilePath);
//       // System.out.println(mp3ResultPath);
//        // 给视频添加字幕
//        //  String subtitleVideoPath = setVideoSubtitles(mp3ResultPath, resultFilePath, subtitlePath);
//        //
//
//    }
}